﻿using GreenXi;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using static GreenXi.GlobalVariables;
using static GreenXi.Help.Can.CanMessage;

namespace PressSystem_Can.Help.Can
{
    public class Can
    {
        #region 状态
        public static bool IsOpen { get; set; } = false;
        public static bool IsInit { get; set; } = false;
        public static bool IsStart { get; set; } = false;
        public static bool IsSendMessageUsed { get; set; } = false;
        #endregion

        #region 新can分析仪
        public const int DEV_USBCAN = 3;
        public const int DEV_USBCAN2 = 4;
        static object Lock = new();


        public static void Start()
        {
            if (IsOpen)
            {
                return;
            }
            if (VCI_OpenDevice(DEV_USBCAN2, 0, 0) != 0)
            {
                IsOpen = true;
                VCI_INIT_CONFIG config = new VCI_INIT_CONFIG();
                config.AccCode = System.Convert.ToUInt32("0x" + "80000008", 16);
                config.AccMask = System.Convert.ToUInt32("0x" + "FFFFFFFF", 16);
                config.Timing0 = System.Convert.ToByte("0x" + "00", 16);
                config.Timing1 = System.Convert.ToByte("0x" + "14", 16);
                config.Filter = (Byte)(1);
                config.Mode = (Byte)0;
                //第0路
                VCI_InitCAN(DEV_USBCAN2, 0, 0, ref config);
                //第1路
                VCI_InitCAN(DEV_USBCAN2, 0, 1, ref config);
                IsInit = true;
                VCI_StartCAN(DEV_USBCAN2, 0, 0);
                VCI_StartCAN(DEV_USBCAN2, 0, 1);

                CanHelper.EnabledServo(1);
                CanHelper.EnabledServo(2);
            }
            else
            {
                IsOpen = false;
                IsInit = false;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="servoId"></param>
        /// <param name="msg"></param>
        /// <param name="Canind">第几路Can</param>
        public static unsafe void SendMessage(int nAxisNum, string msg,string ServoId= "0x00000601")
        {
            lock (Lock)
            {
                VCI_CAN_OBJ sendobj = new VCI_CAN_OBJ();
                sendobj.RemoteFlag = (byte)0;
                sendobj.ExternFlag = (byte)0;
                sendobj.ID = System.Convert.ToUInt32(ServoId, 16);
                int len = (msg.Length + 1) / 3;
                sendobj.DataLen = System.Convert.ToByte(len);
                String strdata = msg;
                int i = -1;
                if (i++ < len - 1)
                    sendobj.Data[0] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[1] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[2] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[3] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[4] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[5] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[6] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                if (i++ < len - 1)
                    sendobj.Data[7] = System.Convert.ToByte("0x" + strdata.Substring(i * 3, 2), 16);
                var aa = VCI_Transmit(DEV_USBCAN2, 0, (uint)nAxisNum - 1, ref sendobj, 1);
                if ( aa== 0)
                {
                    if (CallPolice == 0)
                    {
                        ///失败报警
                        CallPolice = (int)CallPoliceStatus.伺服断开连接;
                    }
                }
                Thread.Sleep(1); // 等待1毫秒的间隔
            }
        }

        //2.定义CAN信息帧的数据类型。
        unsafe public struct VCI_BOARD_INFO //使用不安全代码
        {
            public UInt16 hw_Version;
            public UInt16 fw_Version;
            public UInt16 dr_Version;
            public UInt16 in_Version;
            public UInt16 irq_Num;
            public byte can_Num;

            public fixed byte str_Serial_Num[20];
            public fixed byte str_hw_Type[40];
            public fixed byte Reserved[8];
        }

        public unsafe struct VCI_CAN_OBJ //使用不安全代码
        {
            public uint ID;
            public uint TimeStamp; //时间标识
            public byte TimeFlag; //是否使用时间标识
            public byte SendType; //发送标志。保留，未用
            public byte RemoteFlag; //是否是远程帧
            public byte ExternFlag; //是否是扩展帧
            public byte DataLen; //数据长度
            public fixed byte Data[8]; //数据
            public fixed byte Reserved[3]; //保留位
        }

        //3.定义初始化CAN的数据类型
        public struct VCI_INIT_CONFIG
        {
            public UInt32 AccCode;
            public UInt32 AccMask;
            public UInt32 Reserved;
            public byte Filter; //0或1接收所有帧。2标准帧滤波，3是扩展帧滤波。
            public byte Timing0; //波特率参数，具体配置，请查看二次开发库函数说明书。
            public byte Timing1;
            public byte Mode; //模式，0表示正常模式，1表示只听模式,2自测模式
        }

        /*------------其他数据结构描述---------------------------------*/
        //4.USB-CAN总线适配器板卡信息的数据类型1，该类型为VCI_FindUsbDevice函数的返回参数。
        public struct VCI_BOARD_INFO1
        {
            public UInt16 hw_Version;
            public UInt16 fw_Version;
            public UInt16 dr_Version;
            public UInt16 in_Version;
            public UInt16 irq_Num;
            public byte can_Num;
            public byte Reserved;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] str_Serial_Num;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] str_hw_Type;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] str_Usb_Serial;
        }

        /*------------数据结构描述完成---------------------------------*/

        /*------------兼容ZLG的函数描述---------------------------------*/
        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_OpenDevice(UInt32 DeviceType, UInt32 DeviceInd, UInt32 Reserved);

        [DllImport("controlcan.dll")]
        public static extern UInt32 VCI_CloseDevice(UInt32 DeviceType, UInt32 DeviceInd);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_InitCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_INIT_CONFIG pInitConfig);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_ReadBoardInfo(UInt32 DeviceType, UInt32 DeviceInd, ref VCI_BOARD_INFO pInfo);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_GetReceiveNum(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_ClearBuffer(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_StartCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_ResetCAN(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_Transmit(UInt32 DeviceType, UInt32 DeviceInd, UInt32 CANInd, ref VCI_CAN_OBJ pSend, UInt32 Len);

        [DllImport("controlcan.dll")]
        public static extern UInt32 VCI_Receive(
            UInt32 DeviceType,
            UInt32 DeviceInd,
            UInt32 CANInd,
            ref VCI_CAN_OBJ pReceive,
            UInt32 Len,
            Int32 WaitTime
        );

        /*------------其他函数描述---------------------------------*/

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_ConnectDevice(UInt32 DevType, UInt32 DevIndex);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_UsbDeviceReset(UInt32 DevType, UInt32 DevIndex, UInt32 Reserved);

        [DllImport("controlcan.dll")]
        static extern UInt32 VCI_FindUsbDevice2(ref VCI_BOARD_INFO pInfo);
        /*------------函数描述结束---------------------------------*/
        #endregion

        #region 旧Can分析仪
        //public static int count { get; set; } = 0;

        ///// <summary>
        ///// 设备类型
        ///// </summary>
        //public static uint type { get; set; } = Define.ZCAN_USBCAN2;

        ///// <summary>
        ///// 通道
        ///// </summary>
        //int channel_index_ = 0;

        #region 通讯

        ///// <summary>
        ///// 接收数据处理
        ///// </summary>
        ///// <param name="data"></param>
        ///// <param name="len"></param>
        //public static void ProcessRecvCANData(ZCAN_Receive_Data[] data, uint len)
        //{
        //    string msg = "";
        //    string servoId = "";
        //    int pressNum = 0;
        //    for (uint i = 0; i < len; ++i)
        //    {
        //        ZCAN_Receive_Data can = data[i];
        //        uint id = data[i].frame.can_id;
        //        for (uint j = 0; j < can.frame.can_dlc; ++j)
        //        {
        //            if (servoId == "")
        //            {
        //                CanHelper canHelper = new();
        //                pressNum = (int)can.frame.can_id == 1409 ? 1 : 2;
        //                servoId = canHelper.GetServoId(pressNum);
        //            }
        //            msg = String.Format("{0:G}{1:X2} ", msg, can.frame.data[j]);
        //        }
        //    }
        //    //不同伺服id不同
        //    //根据不同报文进行处理，如获取
        //    //功能码 + 索引号 + 子索引 + 数据
        //    if (msg == "")
        //    {
        //        return;
        //    }
        //    Message message = GetMessage(msg);
        //    //伺服电机上电重新使能
        //    if (message.functionCode == "00" && message.index == "00 00")
        //    {
        //        CanHelper canHelper = new();
        //        canHelper.EnabledServo(servoId);
        //        return;
        //    }

        //    //获取位移数据
        //    if (message.functionCode == "43" && message.index == "64 60")
        //    {
        //        //获取位移并赋值
        //        int puu = GetPuu(message.data);
        //        double Displacement = PuuToDisplacement(puu);

        //        if (pressNum == 1)
        //        {
        //            GlobalVariables.Displacement1 = Displacement;
        //            WeakReferenceMessenger.Default.Send(
        //                new DisplacementMessager(new Displacement { Displacement1 = Displacement })
        //            );
        //        }
        //        else
        //        {
        //            GlobalVariables.Displacement2 = Displacement;
        //            WeakReferenceMessenger.Default.Send(
        //                new DisplacementMessager(new Displacement { Displacement2 = Displacement })
        //            );
        //        }
        //        return;
        //    }

        //    //获取状态数据
        //    if (message.functionCode == "4B" && message.index == "41 60")
        //    {
        //        var messagedataArray = message.data.ToString().Split(" ");
        //        Array.Reverse(messagedataArray);

        //        string reversedString = string.Join(" ", messagedataArray);
        //        string binaryString = string.Join(
        //            "",
        //            reversedString
        //                .Split(' ')
        //                .Select(
        //                    hex => Convert.ToString(Convert.ToInt32(hex, 16), 2).PadLeft(8, '0')
        //                )
        //        );

        //        char[] binaryArray = binaryString.ToCharArray();
        //        Array.Reverse(binaryArray);

        //        WeakReferenceMessenger.Default.Send(
        //            new ServerDriverStatusMessager(
        //                new ServerDriverStatus
        //                {
        //                    IsReadyToSwitchOn = binaryArray[0] == '1',
        //                    IsSwitchOn = binaryArray[1] == '1',
        //                    IsOperationEnabled = binaryArray[2] == '1',
        //                    IsFault = binaryArray[3] == '1',
        //                    IsQuickStop = binaryArray[5] == '1',
        //                    IsSwitchOnDisabled = binaryArray[6] == '1',
        //                    IsWarning = binaryArray[7] == '1',
        //                }
        //            )
        //        );

        //        return;
        //    }
        //}

        //private static double PuuToDisplacement(int puu)
        //{
        //    double a = puu / 1280000.00 * 2.00;
        //    double res = Math.Round(a, 2);//一圈对应2mm
        //    return res;
        //}

        //public bool SendMessage(string stringId, string senddata)
        //{
        //    while (IsSendMessageUsed)
        //    {
        //        Task.Delay(10);
        //    }
        //    uint id = (uint)Convert.ToInt32(stringId, 16);
        //    string data = senddata;
        //    int frame_type_index = 0;
        //    int send_type_index = 0;
        //    uint result; //接受的帧数
        //    ZCAN_Transmit_Data can_data = new();
        //    can_data.frame.can_id = MakeCanId(id, frame_type_index, 0, 0);
        //    can_data.frame.data = new byte[8];
        //    can_data.frame.can_dlc = (byte)SplitData(data, ref can_data.frame.data, CAN_MAX_DLEN);
        //    can_data.transmit_type = (uint)send_type_index;
        //    IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(can_data));
        //    Marshal.StructureToPtr(can_data, ptr, true);

        //    IsSendMessageUsed = true;

        //    result = Method.ZCAN_Transmit(channel_handle_, ptr, 1);
        //    Marshal.FreeHGlobal(ptr);

        //    IsSendMessageUsed = false;

        //    if (result != 1)
        //    {
        //        return false;
        //    }
        //    count++;

        //    return true;
        //}

        #endregion

        #region 数据


        ///// <summary>
        ///// 默认1280000   电机 一圈
        ///// </summary>
        ///// <param name="str"></param>
        ///// <returns></returns>
        //public static int GetPuu(string str)
        //{
        //    string[] strArr = str.Split(' ');
        //    Array.Reverse(strArr);
        //    string reversedString = string.Join(" ", strArr);
        //    string binaryString = string.Join(
        //        "",
        //        reversedString
        //            .Split(' ')
        //            .Select(hex => Convert.ToString(Convert.ToInt32(hex, 16), 2).PadLeft(8, '0'))
        //    );
        //    int decimalValue = Convert.ToInt32(binaryString, 2);

        //    return decimalValue;
        //}

        //public static Message GetMessage(string msg)
        //{
        //    Message message = new();
        //    string[] msgArr = msg.Split(' ');
        //    message.functionCode = msgArr[0];
        //    message.index = msgArr[1] + " " + msgArr[2];
        //    message.subindex = msgArr[3];
        //    message.data = msgArr[4] + " " + msgArr[5] + " " + msgArr[6] + " " + msgArr[7];
        //    return message;
        //}

        ///// <summary>
        ///// 报文
        ///// </summary>
        //public class Message
        //{
        //    /// <summary>
        //    /// 功能码
        //    /// </summary>
        //    public string functionCode = "00";

        //    /// <summary>
        //    /// 索引
        //    /// </summary>
        //    public string index = "00 00";

        //    /// <summary>
        //    /// 子索引
        //    /// </summary>
        //    public string subindex = "00";

        //    /// <summary>
        //    /// 数据
        //    /// </summary>
        //    public string data = "00 00 00 00";
        //}

        #endregion

        //public static uint MakeCanId(uint id, int eff, int rtr, int err) //1:extend frame 0:standard frame
        //{
        //    uint ueff = (uint)(!!(Convert.ToBoolean(eff)) ? 1 : 0);
        //    uint urtr = (uint)(!!(Convert.ToBoolean(rtr)) ? 1 : 0);
        //    uint uerr = (uint)(!!(Convert.ToBoolean(err)) ? 1 : 0);
        //    return id | ueff << 31 | urtr << 30 | uerr << 29;
        //}

        ////拆分text到发送data数组
        //private static int SplitData(string data, ref byte[] transData, int maxLen)
        //{
        //    string[] dataArray = data.Split(' ');
        //    for (int i = 0; (i < maxLen) && (i < dataArray.Length); i++)
        //    {
        //        transData[i] = Convert.ToByte(dataArray[i].Substring(0, 2), 16);
        //    }

        //    return dataArray.Length;
        //}

        //public void Start()
        //{
        //    Open();
        //    Init();
        //    if (!IsOpen || !IsInit)
        //    {
        //        return;
        //    }
        //    if (Method.ZCAN_StartCAN(channel_handle_) != Define.STATUS_OK)
        //    {
        //        return;
        //    }
        //    m_bStart = true;
        //    CanHelper canHelper = new();
        //    //TODO 这里的值应当是变量
        //    string servoId = canHelper.GetServoId(1);
        //    canHelper.EnabledServo(servoId);
        //}

        //private bool Open()
        //{
        //    device_handle_ = Method.ZCAN_OpenDevice(kDeviceType[1].device_type, (uint)0, 0);
        //    GlobalVariables.DeviceHandle = device_handle_;
        //    IsOpen = (int)device_handle_ != NULL;
        //    return IsOpen;
        //}

        //private bool Init()
        //{
        //    if (!IsOpen)
        //    {
        //        return IsOpen;
        //    }

        //    IntPtr ptr = Method.GetIProperty(device_handle_);
        //    if ((Int64)ptr == NULL)
        //    {
        //        //App.Current.Services
        //        //    .GetService<MessageBoxService>()!
        //        //    .ShowOkAsync("设置指定路径属性失败", "提示");
        //        IsInit = false;
        //        return false;
        //    }
        //    property_ = (IProperty)
        //        Marshal.PtrToStructure((IntPtr)((UInt64)ptr), typeof(IProperty))!;

        //    if (!SetBaudrate(1000000))
        //    {
        //        //MessageBox.Show("设置波特率失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        //        IsInit = false;
        //        return false;
        //    }

        //    ZCAN_CHANNEL_INIT_CONFIG config_ = new ZCAN_CHANNEL_INIT_CONFIG();
        //    config_.canfd.mode = 0;
        //    config_.can_type = Define.TYPE_CAN;
        //    config_.can.timing0 = 0;
        //    config_.can.timing1 = 20;
        //    config_.can.filter = 0;
        //    config_.can.acc_code = 0;
        //    config_.can.acc_mask = 0xFFFFFFFF;

        //    IntPtr pConfig = Marshal.AllocHGlobal(Marshal.SizeOf(config_));
        //    Marshal.StructureToPtr(config_, pConfig, true);

        //    channel_handle_ = Method.ZCAN_InitCAN(device_handle_, (uint)channel_index_, pConfig);
        //    GlobalVariables.Channel_handle = channel_handle_;
        //    Marshal.FreeHGlobal(pConfig);

        //    if (NULL == (int)channel_handle_)
        //    {
        //        //MessageBox.Show("初始化CAN失败", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        //        IsInit = false;
        //        return false;
        //    }
        //    IsInit = true;
        //    return true;
        //}

        //public bool IsEFF(uint id) //1:extend frame 0:standard frame
        //{
        //    return !!Convert.ToBoolean((id & CAN_EFF_FLAG));
        //}

        //public bool IsRTR(uint id) //1:remote frame 0:data frame
        //{
        //    return !!Convert.ToBoolean((id & CAN_RTR_FLAG));
        //}

        //public bool IsERR(uint id) //1:error frame 0:normal frame
        //{
        //    return !!Convert.ToBoolean((id & CAN_ERR_FLAG));
        //}

        //public uint GetId(uint id)
        //{
        //    return id & CAN_ID_FLAG;
        //}

        ////设置波特率
        //private bool SetBaudrate(UInt32 baud)
        //{
        //    string path = channel_index_ + "/baud_rate";
        //    string value = baud.ToString();
        //    //char* pathCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(path).ToPointer();
        //    //char* valueCh = (char*)System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(value).ToPointer();
        //    return 1 == property_.SetValue(path, value);
        //}

        #region 引用数据


        //    const int NULL = 0;
        //    const int CANFD_BRS = 0x01; /* bit rate switch (second bitrate for payload data) */
        //    const int CANFD_ESI = 0x02; /* error state indicator of the transmitting node */

        //    /* CAN payload length and DLC definitions according to ISO 11898-1 */
        //    const int CAN_MAX_DLC = 8;
        //    const int CAN_MAX_DLEN = 8;

        //    /* CAN FD payload length and DLC definitions according to ISO 11898-7 */
        //    const int CANFD_MAX_DLC = 15;
        //    const int CANFD_MAX_DLEN = 64;

        //    const uint CAN_EFF_FLAG = 0x80000000U; /* EFF/SFF is set in the MSB */
        //    const uint CAN_RTR_FLAG = 0x40000000U; /* remote transmission request */
        //    const uint CAN_ERR_FLAG = 0x20000000U; /* error message frame */
        //    const uint CAN_ID_FLAG = 0x1FFFFFFFU; /* id */

        //    DeviceInfo[] kDeviceType =
        //    {
        //        new DeviceInfo(Define.ZCAN_USBCAN1, 1),
        //        new DeviceInfo(Define.ZCAN_USBCAN2, 2),
        //        new DeviceInfo(Define.ZCAN_USBCAN_E_U, 1),
        //        new DeviceInfo(Define.ZCAN_USBCAN_2E_U, 2),
        //        new DeviceInfo(Define.ZCAN_PCIECANFD_100U, 1),
        //        new DeviceInfo(Define.ZCAN_PCIECANFD_200U, 2),
        //        new DeviceInfo(Define.ZCAN_PCIECANFD_400U, 4),
        //        new DeviceInfo(Define.ZCAN_USBCANFD_200U, 2),
        //        new DeviceInfo(Define.ZCAN_USBCANFD_100U, 1),
        //        new DeviceInfo(Define.ZCAN_USBCANFD_MINI, 1),
        //        new DeviceInfo(Define.ZCAN_CANETTCP, 1),
        //        new DeviceInfo(Define.ZCAN_CANETUDP, 1),
        //        new DeviceInfo(Define.ZCAN_CLOUD, 1)
        //    };

        //    uint[] kAbitTiming =
        //    {
        //        0x00018B2E, //1Mbps
        //        0x00018E3A, //800kbps
        //        0x0001975E, //500kbps
        //        0x0001AFBE, //250kbps
        //        0x0041AFBE, //125kbps
        //        0x0041BBEE, //100kbps
        //        0x00C1BBEE //50kbps
        //    };

        //    uint[] kDbitTiming =
        //    {
        //        0x00010207, //5Mbps
        //        0x0001020A, //4Mbps
        //        0x0041020A, //2Mbps
        //        0x0081830E //1Mbps
        //    };

        //    byte[] kTiming0 =
        //    {
        //        0x00, //1000kbps
        //        0x00, //800kbps
        //        0x00, //500kbps
        //        0x01, //250kbps
        //        0x03, //125kbps
        //        0x04, //100kbps
        //        0x09, //50kbps
        //        0x18, //20kbps
        //        0x31, //10kbps
        //        0xBF //5kbps
        //    };
        //    byte[] kTiming1 =
        //    {
        //        0x14, //1000kbps
        //        0x16, //800kbps
        //        0x1C, //500kbps
        //        0x1C, //250kbps
        //        0x1C, //125kbps
        //        0x1C, //100kbps
        //        0x1C, //50kbps
        //        0x1C, //20kbps
        //        0x1C, //10kbps
        //        0xFF //5kbps
        //    };
        //    uint[] kBaudrate =
        //    {
        //        1000000, //1000kbps
        //        800000, //800kbps
        //        500000, //500kbps
        //        250000, //250kbps
        //        125000, //125kbps
        //        100000, //100kbps
        //        50000, //50kbps
        //        20000, //20kbps
        //        10000, //10kbps
        //        5000 //5kbps
        //    };

        //    IntPtr device_handle_;
        //    static IntPtr channel_handle_;
        //    IProperty property_;

        //    //bool m_bOpen = false;
        //    //bool m_bCloud = false;
        //    bool m_bStart = false;

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCAN
        //    {
        //        public uint acc_code;
        //        public uint acc_mask;
        //        public uint reserved;
        //        public byte filter;
        //        public byte timing0;
        //        public byte timing1;
        //        public byte mode;
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct CANFD
        //    {
        //        public uint acc_code;
        //        public uint acc_mask;
        //        public uint abit_timing;
        //        public uint dbit_timing;
        //        public uint brp;
        //        public byte filter;
        //        public byte mode;
        //        public UInt16 pad;
        //        public uint reserved;
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct can_frame
        //    {
        //        public uint can_id; /* 32 bit MAKE_CAN_ID + EFF/RTR/ERR flags */
        //        public byte can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
        //        public byte __pad; /* padding */
        //        public byte __res0; /* reserved / padding */
        //        public byte __res1; /* reserved / padding */

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        //        public byte[] data /* __attribute__((aligned(8)))*/
        //        ;
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct canfd_frame
        //    {
        //        public uint can_id; /* 32 bit MAKE_CAN_ID + EFF/RTR/ERR flags */
        //        public byte len; /* frame payload length in byte */
        //        public byte flags; /* additional flags for CAN FD,i.e error code */
        //        public byte __res0; /* reserved / padding */
        //        public byte __res1; /* reserved / padding */

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public byte[] data /* __attribute__((aligned(8)))*/
        //        ;
        //    };

        //    [StructLayout(LayoutKind.Explicit)]
        //    public struct ZCAN_CHANNEL_INIT_CONFIG
        //    {
        //        [FieldOffset(0)]
        //        public uint can_type; //type:TYPE_CAN TYPE_CANFD

        //        [FieldOffset(4)]
        //        public ZCAN can;

        //        [FieldOffset(4)]
        //        public CANFD canfd;
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCAN_Transmit_Data
        //    {
        //        public can_frame frame;
        //        public uint transmit_type;
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCAN_Receive_Data
        //    {
        //        public can_frame frame;
        //        public UInt64 timestamp; //us
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCAN_TransmitFD_Data
        //    {
        //        public canfd_frame frame;
        //        public uint transmit_type;
        //    };

        //    public struct DeviceInfo
        //    {
        //        public uint device_type; //设备类型
        //        public uint channel_count; //设备的通道个数

        //        public DeviceInfo(uint type, uint count)
        //        {
        //            device_type = type;
        //            channel_count = count;
        //        }
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCAN_ReceiveFD_Data
        //    {
        //        public canfd_frame frame;
        //        public UInt64 timestamp; //us
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCAN_CHANNEL_ERROR_INFO
        //    {
        //        public uint error_code;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        //        public byte[] passive_ErrData;
        //        public byte arLost_ErrData;
        //    };

        //    //for zlg cloud
        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCLOUD_DEVINFO
        //    {
        //        public int devIndex;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] type;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] id;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] owner;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] model;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        //        public char[] fwVer;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        //        public char[] hwVer;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] serial;
        //        public byte canNum;
        //        public int status; // 0:online, 1:offline

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        //        public byte[] bCanUploads; // each channel enable can upload
        //        public byte bGpsUpload;
        //    };

        //    [StructLayout(LayoutKind.Sequential)]
        //    public struct ZCLOUD_USER_DATA
        //    {
        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] username;

        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        public char[] mobile;

        //        //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        //        // public char[] email;
        //        // public IntPtr pDevGroups;
        //        // public uint devGroupSize;
        //        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
        //        public ZCLOUD_DEVINFO[] devices;
        //        public uint devCnt;
        //    };

        //    public class Define
        //    {
        //        public const int TYPE_CAN = 0;
        //        public const int TYPE_CANFD = 1;

        //        public const int ZCAN_USBCAN1 = 3;
        //        public const int ZCAN_USBCAN2 = 4;
        //        public const int ZCAN_CANETUDP = 12;
        //        public const int ZCAN_CANETTCP = 17;
        //        public const int ZCAN_USBCAN_E_U = 20;
        //        public const int ZCAN_USBCAN_2E_U = 21;
        //        public const int ZCAN_PCIECANFD_100U = 38;
        //        public const int ZCAN_PCIECANFD_200U = 39;
        //        public const int ZCAN_PCIECANFD_400U = 40;
        //        public const int ZCAN_USBCANFD_200U = 41;
        //        public const int ZCAN_USBCANFD_100U = 42;
        //        public const int ZCAN_USBCANFD_MINI = 43;
        //        public const int ZCAN_CLOUD = 46;

        //        public const int STATUS_ERR = 0;
        //        public const int STATUS_OK = 1;
        //    };

        //    public class Method
        //    {
        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern IntPtr ZCAN_OpenDevice(
        //            uint device_type,
        //            uint device_index,
        //            uint reserved
        //        );

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern uint ZCAN_CloseDevice(IntPtr device_handle);

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        // pInitConfig -> ZCAN_CHANNEL_INIT_CONFIG
        //        public static extern IntPtr ZCAN_InitCAN(
        //            IntPtr device_handle,
        //            uint can_index,
        //            IntPtr pInitConfig
        //        );

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern uint ZCAN_StartCAN(IntPtr channel_handle);

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern uint ZCAN_ResetCAN(IntPtr channel_handle);

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        // pTransmit -> ZCAN_Transmit_Data
        //        public static extern uint ZCAN_Transmit(
        //            IntPtr channel_handle,
        //            IntPtr pTransmit,
        //            uint len
        //        );

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern uint ZCAN_GetReceiveNum(IntPtr channel_handle, byte type);

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern uint ZCAN_Receive(
        //            IntPtr channel_handle,
        //            IntPtr data,
        //            uint len,
        //            int wait_time = -1
        //        );

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        // pErrInfo -> ZCAN_CHANNEL_ERROR_INFO
        //        public static extern uint ZCAN_ReadChannelErrInfo(
        //            IntPtr channel_handle,
        //            IntPtr pErrInfo
        //        );

        //        [DllImport("zlgcan.dll", CallingConvention = CallingConvention.StdCall)]
        //        public static extern IntPtr GetIProperty(IntPtr device_handle);
        //    }

        //    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        //    public delegate int SetValueFunc(string path, string value);

        //    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        //    public delegate string GetValueFunc(string path, string value);

        //    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        //    public delegate IntPtr GetPropertysFunc(string path, string value);

        //    public struct IProperty
        //    {
        //        public SetValueFunc SetValue;
        //        public GetValueFunc GetValue;
        //        public GetPropertysFunc GetPropertys;
        //    };
        #endregion
        #endregion
    }
}
